package com.elegantmall.service;

import com.elegantmall.dao.GoodsDao;
import com.elegantmall.dao.SalesReportDao;
import com.elegantmall.dto.SalesReportDTO;
import com.elegantmall.dto.TextReportDTO;
import com.elegantmall.dto.SalesReportDTO.PopularProductDTO;
import com.elegantmall.dto.SalesReportDTO.CategorySalesDTO;
import com.elegantmall.pojo.GoodsPojo;
import com.elegantmall.pojo.OrderPojo;
import com.elegantmall.util.ChartUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional(rollbackFor = Exception.class)
public class SalesReportServiceImpl {

    @Autowired
    private SalesReportDao salesReportDao;
    
    @Autowired
    private GoodsDao goodsDao;

    /**
     * 生成销售报告
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 销售报告数据
     */
    public SalesReportDTO generateSalesReport(Date startDate, Date endDate) {
        SalesReportDTO report = new SalesReportDTO();
        report.setGeneratedTime(new Date());
        report.setStartDate(startDate);
        report.setEndDate(endDate);
        
        // 获取总订单数
        Integer totalOrders = salesReportDao.getTotalOrders(startDate, endDate);
        report.setTotalOrders(totalOrders != null ? totalOrders : 0);
        
        // 获取总销售额
        Double totalSales = salesReportDao.getTotalSales(startDate, endDate);
        report.setTotalSales(totalSales != null ? totalSales : 0.0);
        
        // 获取最受欢迎商品列表
        List<Map<String, Object>> productStats = salesReportDao.getProductSalesStats(startDate, endDate);
        List<PopularProductDTO> popularProducts = convertToPopularProducts(productStats);
        report.setPopularProducts(popularProducts);
        
        // 获取各类别销售数据
        List<Map<String, Object>> categoryStats = salesReportDao.getCategorySalesStats(startDate, endDate);
        List<CategorySalesDTO> categorySales = convertToCategorySales(categoryStats, totalSales != null ? totalSales : 0.0);
        report.setCategorySales(categorySales);
        
        // 在业务层计算销售趋势数据
        List<OrderPojo> orders = salesReportDao.getOrdersByDateRange(startDate, endDate);
        Map<String, Double> salesTrend = calculateSalesTrend(orders);
        report.setSalesTrend(salesTrend);
        
        return report;
    }

    /**
     * 生成某个卖家的销售报告
     * @param sellerName 卖家名称
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 销售报告数据
     */
    public SalesReportDTO generateSellerSalesReport(String sellerName, Date startDate, Date endDate) {
        SalesReportDTO report = new SalesReportDTO();
        report.setGeneratedTime(new Date());
        report.setStartDate(startDate);
        report.setEndDate(endDate);
        
        // 获取该卖家的订单
        List<OrderPojo> orders = salesReportDao.getOrdersBySellerAndDateRange(sellerName, startDate, endDate);
        report.setTotalOrders(orders.size());
        
        // 获取该卖家的总销售额（通过统计每个商品的销售额并求和）
        Double totalSales = 0.0;
        List<Map<String, Object>> sellerProductStats = salesReportDao.getSellerProductSalesStats(sellerName, startDate, endDate);
        
        for (Map<String, Object> stat : sellerProductStats) {
            if (stat.get("total_revenue") != null) {
                totalSales += ((Number) stat.get("total_revenue")).doubleValue();
            }
        }
        report.setTotalSales(totalSales);
        
        // 获取该卖家最受欢迎商品列表
        List<PopularProductDTO> popularProducts = convertToPopularProducts(sellerProductStats);
        report.setPopularProducts(popularProducts);
        
        // 获取该卖家各类别销售数据
        Map<String, CategorySalesDTO> categorySalesMap = new HashMap<>();
        for (Map<String, Object> stat : sellerProductStats) {
            String category = (String) stat.get("category");
            double revenue = ((Number) stat.get("total_revenue")).doubleValue();
            int sold = ((Number) stat.get("total_sold")).intValue();
            
            CategorySalesDTO categorySales = categorySalesMap.getOrDefault(category, new CategorySalesDTO());
            categorySales.setCategory(category);
            categorySales.setTotalSold(categorySales.getTotalSold() + sold);
            categorySales.setTotalRevenue(categorySales.getTotalRevenue() + revenue);
            categorySalesMap.put(category, categorySales);
        }
        
        // 计算各类别销售占比
        List<CategorySalesDTO> categorySalesList = new ArrayList<>();
        for (CategorySalesDTO categorySales : categorySalesMap.values()) {
            categorySales.setPercentageOfTotal(totalSales > 0 ? (categorySales.getTotalRevenue() / totalSales) * 100 : 0);
            categorySalesList.add(categorySales);
        }
        categorySalesList.sort((c1, c2) -> Double.compare(c2.getTotalRevenue(), c1.getTotalRevenue()));
        report.setCategorySales(categorySalesList);
        
        // 在业务层计算销售趋势
        Map<String, Double> salesTrend = calculateSalesTrend(orders);
        report.setSalesTrend(salesTrend);
        
        return report;
    }

    /**
     * 生成特定类别的销售报告
     * @param category 商品类别
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 销售报告数据
     */
    public SalesReportDTO generateCategorySalesReport(String category, Date startDate, Date endDate) {
        SalesReportDTO report = new SalesReportDTO();
        report.setGeneratedTime(new Date());
        report.setStartDate(startDate);
        report.setEndDate(endDate);
        
        // 获取特定类别的商品销售统计
        List<Map<String, Object>> productStats = salesReportDao.getProductSalesStats(startDate, endDate);
        List<PopularProductDTO> allProducts = convertToPopularProducts(productStats);
        
        // 过滤出指定类别的商品
        List<PopularProductDTO> categoryProducts = new ArrayList<>();
        double categoryTotalSales = 0.0;
        int categoryTotalSold = 0;
        
        for (PopularProductDTO product : allProducts) {
            if (category.equals(product.getCategory())) {
                categoryProducts.add(product);
                categoryTotalSales += product.getTotalRevenue();
                categoryTotalSold += product.getTotalSold();
            }
        }
        
        report.setPopularProducts(categoryProducts);
        report.setTotalSales(categoryTotalSales);
        report.setTotalOrders(categoryTotalSold); // 注意：这里是商品销售总数而不是订单数
        
        // 类别销售数据（只有一个类别）
        List<CategorySalesDTO> categorySalesList = new ArrayList<>();
        CategorySalesDTO categorySales = new CategorySalesDTO();
        categorySales.setCategory(category);
        categorySales.setTotalSold(categoryTotalSold);
        categorySales.setTotalRevenue(categoryTotalSales);
        categorySales.setPercentageOfTotal(100.0); // 因为只有一个类别，所以占比是100%
        categorySalesList.add(categorySales);
        report.setCategorySales(categorySalesList);
        
        // 在业务层计算销售趋势
        List<OrderPojo> categoryOrders = salesReportDao.getOrdersByCategoryAndDateRange(category, startDate, endDate);
        Map<String, Double> salesTrend = calculateSalesTrend(categoryOrders);
        report.setSalesTrend(salesTrend);
        
        return report;
    }
    
    /**
     * 将数据库查询结果转换为最受欢迎商品列表
     */
    private List<PopularProductDTO> convertToPopularProducts(List<Map<String, Object>> productStats) {
        List<PopularProductDTO> popularProducts = new ArrayList<>();
        for (Map<String, Object> stat : productStats) {
            PopularProductDTO product = new PopularProductDTO();
            product.setGoodsId((String) stat.get("goods_id"));
            product.setGoodsName((String) stat.get("goods_name"));
            product.setCategory((String) stat.get("category"));
            product.setTotalSold(((Number) stat.get("total_sold")).intValue());
            product.setTotalRevenue(((Number) stat.get("total_revenue")).doubleValue());
            popularProducts.add(product);
        }
        return popularProducts;
    }
    
    /**
     * 将数据库查询结果转换为类别销售数据
     */
    private List<CategorySalesDTO> convertToCategorySales(List<Map<String, Object>> categoryStats, double totalSales) {
        List<CategorySalesDTO> categorySalesList = new ArrayList<>();
        for (Map<String, Object> stat : categoryStats) {
            CategorySalesDTO categorySales = new CategorySalesDTO();
            categorySales.setCategory((String) stat.get("category"));
            categorySales.setTotalSold(((Number) stat.get("total_sold")).intValue());
            categorySales.setTotalRevenue(((Number) stat.get("total_revenue")).doubleValue());
            categorySales.setPercentageOfTotal(totalSales > 0 ? (categorySales.getTotalRevenue() / totalSales) * 100 : 0);
            categorySalesList.add(categorySales);
        }
        return categorySalesList;
    }
    
    /**
     * 在业务层计算销售趋势数据
     */
    private Map<String, Double> calculateSalesTrend(List<OrderPojo> orders) {
        Map<String, Double> salesTrend = new TreeMap<>(); // 使用TreeMap确保日期排序
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        
        for (OrderPojo order : orders) {
            if (order.getCreateTime() != null) {
                String dateStr = dateFormat.format(order.getCreateTime());
                
                // 获取商品信息计算销售额
                GoodsPojo goods = goodsDao.selectById(order.getGoodsId());
                if (goods != null) {
                    double orderRevenue = goods.getPrice() * order.getNumber();
                    salesTrend.put(dateStr, salesTrend.getOrDefault(dateStr, 0.0) + orderRevenue);
                }
            }
        }
        
        return salesTrend;
    }

    /**
     * 生成销售报告的文字版本
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 文字版销售报告
     */
    public TextReportDTO generateTextSalesReport(Date startDate, Date endDate) {
        // 先获取销售报告数据
        SalesReportDTO reportData = generateSalesReport(startDate, endDate);
        
        // 创建文字报告
        TextReportDTO textReport = new TextReportDTO();
        textReport.setTitle("销售数据分析报告");
        textReport.setGeneratedTime(new Date());
        textReport.setStartDate(startDate);
        textReport.setEndDate(endDate);
        
        // 格式化日期和数字
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        DecimalFormat moneyFormat = new DecimalFormat("#,##0.00");
        DecimalFormat percentFormat = new DecimalFormat("#0.00");
        
        // 构建报告内容
        StringBuilder content = new StringBuilder();
        
        // 基本信息部分
        content.append("# 销售数据分析报告\n\n");
        content.append("报告生成时间：").append(dateFormat.format(textReport.getGeneratedTime())).append("\n");
        content.append("统计时间范围：").append(dateFormat.format(startDate)).append(" 至 ").append(dateFormat.format(endDate)).append("\n\n");
        
        // 总体概况部分
        content.append("## 总体销售概况\n\n");
        content.append("总销售额：￥").append(moneyFormat.format(reportData.getTotalSales())).append("\n");
        content.append("总订单数：").append(reportData.getTotalOrders()).append("个\n\n");
        
        // 最受欢迎商品部分
        content.append("## 最受欢迎商品TOP5\n\n");
        List<PopularProductDTO> popularProducts = reportData.getPopularProducts();
        int productCount = Math.min(5, popularProducts.size());
        for (int i = 0; i < productCount; i++) {
            PopularProductDTO product = popularProducts.get(i);
            content.append(i + 1).append(". ").append(product.getGoodsName())
                  .append("（类别：").append(product.getCategory()).append("）\n")
                  .append("   销售数量：").append(product.getTotalSold()).append("件，")
                  .append("销售额：￥").append(moneyFormat.format(product.getTotalRevenue())).append("\n");
        }
        content.append("\n");
        
        // 类别销售情况部分
        content.append("## 各类别销售情况\n\n");
        List<CategorySalesDTO> categorySales = reportData.getCategorySales();
        for (CategorySalesDTO category : categorySales) {
            content.append("- ").append(category.getCategory())
                  .append("：销售").append(category.getTotalSold()).append("件，")
                  .append("销售额￥").append(moneyFormat.format(category.getTotalRevenue()))
                  .append("，占比").append(percentFormat.format(category.getPercentageOfTotal())).append("%\n");
        }
        content.append("\n");
        
        // 销售趋势分析部分
        content.append("## 销售趋势分析\n\n");
        Map<String, Double> salesTrend = reportData.getSalesTrend();
        content.append("本报告期内，销售额波动情况如下图所示。");
        
        // 查找销售高峰
        Map.Entry<String, Double> peakDay = findPeakSalesDay(salesTrend);
        if (peakDay != null) {
            content.append("销售高峰出现在").append(peakDay.getKey()).append("，达到￥")
                  .append(moneyFormat.format(peakDay.getValue())).append("。");
        }
        
        // 分析趋势
        String trendAnalysis = analyzeSalesTrend(salesTrend);
        content.append(trendAnalysis).append("\n\n");
        
        // 建议部分
        content.append("## 经营建议\n\n");
        
        // 基于最受欢迎商品的建议
        if (!popularProducts.isEmpty()) {
            content.append("1. **商品策略**：继续重点推广")
                  .append(popularProducts.get(0).getGoodsName())
                  .append("等热销商品，考虑增加库存和相关产品线。\n");
        }
        
        // 基于类别销售的建议
        if (!categorySales.isEmpty()) {
            CategorySalesDTO topCategory = categorySales.get(0);
            CategorySalesDTO lastCategory = categorySales.get(categorySales.size() - 1);
            content.append("2. **类别优化**：重点关注")
                  .append(topCategory.getCategory())
                  .append("类别，该类别贡献了最高的销售额。考虑对")
                  .append(lastCategory.getCategory())
                  .append("类别进行优化或调整。\n");
        }
        
        // 基于销售趋势的建议
        content.append("3. **营销时机**：根据销售趋势图，选择在销售高峰前进行营销活动，提前做好库存准备。\n\n");
        
        // 结束语
        content.append("## 结语\n\n");
        content.append("以上是本期销售数据分析报告，希望能为您的经营决策提供参考。");
        
        // 设置报告内容
        textReport.setContent(content.toString());
        
        // 生成趋势图并设置Base64编码
        String chartTitle = "销售趋势图 (" + dateFormat.format(startDate) + " - " + dateFormat.format(endDate) + ")";
        String chartBase64 = ChartUtil.generateSalesTrendChart(salesTrend, chartTitle);
        textReport.setTrendChartBase64(chartBase64);
        
        return textReport;
    }
    
    /**
     * 生成某个卖家的文字版销售报告
     * @param sellerName 卖家名称
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 卖家文字版销售报告
     */
    public TextReportDTO generateTextSellerSalesReport(String sellerName, Date startDate, Date endDate) {
        // 先获取卖家销售报告数据
        SalesReportDTO reportData = generateSellerSalesReport(sellerName, startDate, endDate);
        
        // 创建文字报告
        TextReportDTO textReport = new TextReportDTO();
        textReport.setTitle(sellerName + "的销售数据分析报告");
        textReport.setGeneratedTime(new Date());
        textReport.setStartDate(startDate);
        textReport.setEndDate(endDate);
        
        // 格式化日期和数字
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        DecimalFormat moneyFormat = new DecimalFormat("#,##0.00");
        DecimalFormat percentFormat = new DecimalFormat("#0.00");
        
        // 构建报告内容
        StringBuilder content = new StringBuilder();
        
        // 基本信息部分
        content.append("# ").append(sellerName).append("的销售数据分析报告\n\n");
        content.append("报告生成时间：").append(dateFormat.format(textReport.getGeneratedTime())).append("\n");
        content.append("统计时间范围：").append(dateFormat.format(startDate)).append(" 至 ").append(dateFormat.format(endDate)).append("\n\n");
        
        // 总体概况部分
        content.append("## 总体销售概况\n\n");
        content.append("总销售额：￥").append(moneyFormat.format(reportData.getTotalSales())).append("\n");
        content.append("总订单数：").append(reportData.getTotalOrders()).append("个\n\n");
        
        // 最受欢迎商品部分
        content.append("## 最受欢迎商品TOP5\n\n");
        List<PopularProductDTO> popularProducts = reportData.getPopularProducts();
        int productCount = Math.min(5, popularProducts.size());
        for (int i = 0; i < productCount; i++) {
            PopularProductDTO product = popularProducts.get(i);
            content.append(i + 1).append(". ").append(product.getGoodsName())
                  .append("（类别：").append(product.getCategory()).append("）\n")
                  .append("   销售数量：").append(product.getTotalSold()).append("件，")
                  .append("销售额：￥").append(moneyFormat.format(product.getTotalRevenue())).append("\n");
        }
        content.append("\n");
        
        // 类别销售情况部分
        content.append("## 各类别销售情况\n\n");
        List<CategorySalesDTO> categorySales = reportData.getCategorySales();
        for (CategorySalesDTO category : categorySales) {
            content.append("- ").append(category.getCategory())
                  .append("：销售").append(category.getTotalSold()).append("件，")
                  .append("销售额￥").append(moneyFormat.format(category.getTotalRevenue()))
                  .append("，占比").append(percentFormat.format(category.getPercentageOfTotal())).append("%\n");
        }
        content.append("\n");
        
        // 销售趋势分析部分
        content.append("## 销售趋势分析\n\n");
        Map<String, Double> salesTrend = reportData.getSalesTrend();
        content.append("本报告期内，").append(sellerName).append("的销售额波动情况如下图所示。");
        
        // 查找销售高峰
        Map.Entry<String, Double> peakDay = findPeakSalesDay(salesTrend);
        if (peakDay != null) {
            content.append("销售高峰出现在").append(peakDay.getKey()).append("，达到￥")
                  .append(moneyFormat.format(peakDay.getValue())).append("。");
        }
        
        // 分析趋势
        String trendAnalysis = analyzeSalesTrend(salesTrend);
        content.append(trendAnalysis).append("\n\n");
        
        // 建议部分
        content.append("## 经营建议\n\n");
        
        // 基于最受欢迎商品的建议
        if (!popularProducts.isEmpty()) {
            content.append("1. **商品策略**：继续重点推广")
                  .append(popularProducts.get(0).getGoodsName())
                  .append("等热销商品，考虑增加库存和相关产品线。\n");
        }
        
        // 基于类别销售的建议
        if (!categorySales.isEmpty()) {
            CategorySalesDTO topCategory = categorySales.get(0);
            content.append("2. **类别优化**：重点关注")
                  .append(topCategory.getCategory())
                  .append("类别，该类别贡献了最高的销售额。\n");
        }
        
        // 基于销售趋势的建议
        content.append("3. **营销时机**：根据销售趋势图，选择在销售高峰前进行营销活动，提前做好库存准备。\n\n");
        
        // 结束语
        content.append("## 结语\n\n");
        content.append("以上是").append(sellerName).append("本期销售数据分析报告，希望能为您的经营决策提供参考。");
        
        // 设置报告内容
        textReport.setContent(content.toString());
        
        // 生成趋势图并设置Base64编码
        String chartTitle = sellerName + "的销售趋势图 (" + dateFormat.format(startDate) + " - " + dateFormat.format(endDate) + ")";
        String chartBase64 = ChartUtil.generateSalesTrendChart(salesTrend, chartTitle);
        textReport.setTrendChartBase64(chartBase64);
        
        return textReport;
    }
    
    /**
     * 查找销售高峰日
     */
    private Map.Entry<String, Double> findPeakSalesDay(Map<String, Double> salesTrend) {
        if (salesTrend == null || salesTrend.isEmpty()) {
            return null;
        }
        
        return Collections.max(salesTrend.entrySet(), Map.Entry.comparingByValue());
    }
    
    /**
     * 分析销售趋势
     */
    private String analyzeSalesTrend(Map<String, Double> salesTrend) {
        if (salesTrend == null || salesTrend.isEmpty() || salesTrend.size() < 2) {
            return "数据不足，无法分析销售趋势。";
        }
        
        // 计算平均值
        double sum = 0;
        for (Double value : salesTrend.values()) {
            sum += value;
        }
        double average = sum / salesTrend.size();
        
        // 分析波动性
        double variance = 0;
        for (Double value : salesTrend.values()) {
            variance += Math.pow(value - average, 2);
        }
        variance = variance / salesTrend.size();
        double stdDev = Math.sqrt(variance);
        double coefficient = stdDev / average;
        
        StringBuilder analysis = new StringBuilder();
        
        // 根据波动系数分析趋势
        if (coefficient < 0.1) {
            analysis.append("销售额相对稳定，波动较小。");
        } else if (coefficient < 0.3) {
            analysis.append("销售额有一定波动，但整体较为稳定。");
        } else if (coefficient < 0.5) {
            analysis.append("销售额波动明显，需要关注销售高峰与低谷。");
        } else {
            analysis.append("销售额波动剧烈，建议深入分析销售高峰与低谷的原因。");
        }
        
        // 分析趋势方向
        List<Double> values = new ArrayList<>(salesTrend.values());
        int size = values.size();
        int riseDays = 0;
        
        for (int i = 1; i < size; i++) {
            if (values.get(i) > values.get(i - 1)) {
                riseDays++;
            }
        }
        
        double riseRate = (double) riseDays / (size - 1);
        
        if (riseRate > 0.6) {
            analysis.append("整体呈上升趋势，销售情况良好。");
        } else if (riseRate < 0.4) {
            analysis.append("整体呈下降趋势，需要关注并采取措施改善。");
        } else {
            analysis.append("销售趋势波动，没有明显的上升或下降趋势。");
        }
        
        return analysis.toString();
    }
} 